-- Sorting function for structured associative arrays (indexed dictionaries), sorted by second value which needs to be numeric
-- Zero values sort are returned last
function dictionarySort(a,b)
	if a[2] == 0 and b[2] ~= 0 then return false end
	if b[2] == 0 and a[2] ~= 0 then return true end
	if a[2] ~= 0 then return a[2] < b[2] end
	return a[1] < b[1]
end

-- Takes a dictionary with positions as value, returns sorted array by positions.
function dictOfKeyPositionToSortedArray(dictionary)
	local enabledDataElements = {};
	
	-- Create an array of dictionaries so it can be sorted
	for k,v in pairs(dictionary) do -- For each Data element
		if v > 0 then --If value is supposed to be visible
			enabledDataElements[k] = v;
		end
	end
	
	-- Sort Dictionaries by value and return as sorted array
	return dictToSortedArray(enabledDataElements);
end

-- Create a dictionary from an array of dictionaries
function arrayOfDictToDict(array)
	local simpleDictionary  = {};
	for i,v in ipairs(array) do
		simpleDictionary[v[1]] = v[2];
	end
	return simpleDictionary;
end

-- Create simple sorted array from array of dictionaries
function arrayOfDictToArray(array)
	local sortedArray  = {};
	
	for i,v in ipairs(array) do
		table.insert(sortedArray,v[1]);
	end
	
	return sortedArray;
end

-- Sort a Dictionary by it's values, return array in same order
function dictToSortedArray(elements)
	local sortedArrayOfDictionaries = dictToSortedArrayOfDict(elements);
	return arrayOfDictToArray(sortedArrayOfDictionaries);
end

-- Sort a Dictionary by it's values, return array of dictionaries in specified order
function dictToSortedArrayOfDict(elements)
	local arrayOfDictionaries = {};
	
	-- Convert dictionary to array of dictionaries
	for k,v in pairs(elements) do 
		table.insert(arrayOfDictionaries,{k,v});
	end
	
	-- Sort using dictionarySort function
	table.sort(arrayOfDictionaries, dictionarySort)
	
	return arrayOfDictionaries;
end

-- Merge two dictionaries, keys in second overwrite first
function mergeDict(dict1, dict2)
	local mergedDict = {};
	for k,v in pairs(dict1) do
		mergedDict[k] = dict1[k];
	end
	for k,v in pairs(dict2) do
		mergedDict[k] = dict2[k];
	end
	return mergedDict;
end

-- Reassign positional values in key, position dictionary based on encapsulating array
function reProcessDictByParentArray(elements)
	for i,v in ipairs(elements) do
		if v[2] > 0 then
			elements[i][2] = i;
		end
	end
end

-- Create a dictionary from two arrays containing keys and values
function twoArraysToDict(keys,values)
	local dictionary = {};
	for i in pairs(keys) do
		dictionary[keys[i]] = values[i];
	end
	return dictionary;
end

-- Deep Copy, copy object instead of using "pointers"
function deepcopy(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for index, value in pairs(object) do
            new_table[_copy(index)] = _copy(value)
        end
        return setmetatable(new_table, getmetatable(object))
    end
    return _copy(object)
end